﻿#region Header
// Copyright 2007-2011, Jerónimo Milea
// 
// This file is part of NetJsWire.
// 
//     NetJsWire is free software: you can redistribute it and/or modify
//     it under the terms of the GNU General Public License as published by
//     the Free Software Foundation, either version 3 of the License, or
//     (at your option) any later version.
// 
//     NetJsWire is distributed in the hope that it will be useful,
//     but WITHOUT ANY WARRANTY; without even the implied warranty of
//     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//     GNU General Public License for more details.
// 
//     You should have received a copy of the GNU General Public License
//     along with NetJsWire.  If not, see <http://www.gnu.org/licenses/>.
#endregion

using System;
using System.Linq;
using System.Reflection;
using System.Web;
using NetJsWire.Direct.helper;

namespace NetJsWire.Direct
{
    /// <summary>
    ///   Represents the Proxy For Ext.Direct Comunication.
    ///   Tha ProccessRequest Methode scanns all the available Assembly for Classes and Methods with the 
    ///   Direct Attribute.
    /// </summary>
    public class DirectProxy : IHttpHandler
    {
        private static string _url = "";
        public static string RouterUrl
        {
            get { return _url; }
            set { _url = value; }
        }

        #region IHttpHandler Members

        public void ProcessRequest( HttpContext context )
        {

            context.Response.ContentType = "application/javascript";
            // set default namspace for the remoting API
            var apiNamespace = "Ext.app.REMOTING_API";
            if ( context.Request.Form[ "ns" ] != null )
            {
                // if there is an namespace parameter, use it...
                apiNamespace = context.Request.Form[ "ns" ];
            }
            var provider = GetDirectProviderCache( apiNamespace );

            context.Response.Write( provider.ToString() );
            context.Response.Write( "Ext.Direct.addProvider(Ext.app.REMOTING_API);" );
            /*
            old code..
           
            
            // set the Response typ to javascript since the responce gets Parsed into an Script Tag
            context.Response.ContentType = "text/JavaScript";

            string rem = "{";
            rem += "url: \""+routerUrl+"\",";
            rem += "type:\"remoting\",";


            //string json = DirectProxyGenerator.generateDirectApi();
           //rem += json;
            rem += "};";

            rem = apiNamespace + ".REMOTING_API =" + rem;
            rem = "(function(){" + rem + "})();";

            context.Response.Write(rem);
           */
        }

        public bool IsReusable
        {
            get { return false; }
        }

        #endregion

        public static DirectProvider GetDirectProviderCache( string apiNameSpace )
        {

            var routerUrl = ( RouterUrl == "" ) ? ConfigurationCache.getRouterUrl() : RouterUrl;

            // set default namspace for the remoting API
            var apiNamespace = string.IsNullOrWhiteSpace( apiNameSpace ) ? "Ext.app.REMOTING_API" : apiNameSpace;


            var cache = DirectProviderCache.GetInstance();
            DirectProvider provider;

            //After being configured, the provider should be cached.
            if ( !cache.ContainsKey( apiNamespace + "/" + routerUrl ) )
            {
                provider = new DirectProvider( apiNamespace, routerUrl );
                provider.Configure( AppDomain.CurrentDomain.GetAssemblies() );
                provider.Configure( Assembly.GetExecutingAssembly().GetTypes().ToList() );
                if ( !cache.ContainsKey( apiNamespace + "/" + routerUrl ) )
                    cache.Add( apiNamespace + "/" + routerUrl, provider );
            }
            else
            {
                provider = cache[ apiNamespace + "/" + routerUrl ];
            }
            return provider;
        }
    }
}
